import { PrismaService } from '@/prisma/prisma.service';
import { dateFormat } from '@/util';
import { Injectable } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { PrismaClient } from '@prisma/client';
import { AnyCnameRecord } from 'dns';
import moment from 'moment';
import nodemailer from 'nodemailer';
import { CreateSendMailDto } from './dto/create-send.mail.dto';
import { queyrDataDto } from './dto/queyrDataDto';
@Injectable()
export class SendMailService {
  constructor(private prisma: PrismaService, private config: ConfigService) {}
  async create(createSendMailDto: CreateSendMailDto, req) {
    if (createSendMailDto.id) {
      const result = await this.prisma.postOffice.update({
        data: {
          content: createSendMailDto.content,
          emailAddress: createSendMailDto.emailAddress,
          sendDate: new Date(createSendMailDto.sendDate),
          userId: req.user.id,
          isPublic: Boolean(createSendMailDto.isPublic),
          name: createSendMailDto.name,
        },
        where: {
          id: +createSendMailDto.id,
        },
      });
      return result;
    } else {
      // console.log('createSendMailDto', createSendMailDto);
      const result = await this.prisma.postOffice.create({
        data: {
          content: createSendMailDto.content,
          emailAddress: createSendMailDto.emailAddress,
          sendDate: new Date(createSendMailDto.sendDate),
          userId: req.user.id,
          isPublic: Boolean(createSendMailDto.isPublic),
          name: createSendMailDto.name,
        },
      });
      return result;
    }
  }

  async randomReading() {
    const records = await this.prisma.postOffice.findMany({
      where: {
        isPublic: true,
      },
    });
    const randomIndex = Math.floor(Math.random() * records.length);
    if (records.length === 0) {
      return {};
    }
    const result: any = records[randomIndex];
    result.emailAddress = this.desensitization(result.emailAddress, '*');
    result.name = this.desensitization(result.name, '*');
    result.sendDate = moment(result.sendDate).format('YYYY-MM-DD');
    return result;
  }
  async sednMail(addressee: string, name: string, content: string) {
    const sendAddress = '42873016@qq.com';
    //引入模块 nodemailer
    // 创建一个SMTP客户端配置
    const config = {
      service: 'QQ',
      auth: {
        // 发件人邮箱账号
        user: sendAddress,
        //发件人邮箱的授权码 这里可以通过qq邮箱获取 并且不唯一
        pass: this.config.get('EMAIL_SECRET'),
      },
    };
    const transporter = nodemailer.createTransport(config);
    const mail = {
      // 发件人 邮箱  '昵称<发件人邮箱>'
      from: `时光邮局<42873016@qq.com>'`,
      // 主题
      subject: `${name}！！！时光邮局这有一封你的信`,
      // 收件人 的邮箱 可以是其他邮箱 不一定是qq邮箱
      to: addressee,
      //这里可以添加html标签
      html: `<div>${content}</div>`,
    };
    let result = '';
    try {
      result = await transporter.sendMail(mail);
    } catch (e) {
      console.log('error', e);
    }
    return result;
  }
  async findAll(query: queyrDataDto) {
    const result: any = await this.prisma.postOffice.findMany({
      skip: (query.page - 1) * query.size,
      take: +query.size,
    });
    result.map((e) => {
      e.name = this.desensitization(e.name, '*');
      e.emailAddress = this.desensitization(e.emailAddress, '*');
      e.createTime = moment(e.createTime).format('YYYY-MM-DD');
      e.sendDate = moment(e.sendDate).format('YYYY-MM-DD');
    });
    return {
      meta: {
        total: await this.prisma.postOffice.count(),
        currentPage: query.page,
      },
      data: result,
    };
  }

  async findSelfMail(req: any) {
    const result: Array<any> = await this.prisma.postOffice.findMany({
      where: {
        id: req.id,
      },
    });
    result.map((e) => {
      e.updateTime = moment(e.updateTime).format('YYYY-MM-DD');
      e.sendDate = moment(e.sendDate).format('YYYY-MM-DD');
    });
    return result;
  }
  async remove(id: string) {
    const result = await this.prisma.postOffice.delete({
      where: {
        id: +id,
      },
    });
    return result;
  }
  // 数据脱敏
  desensitization(str: string, mark: string) {
    if (!str || str.length == 0) {
      return '';
    }
    mark = mark || '*';
    const dl = Math.floor(str.length * 0.6);
    let dlstr = '';
    for (let i = 0; i < dl; i++) {
      dlstr += mark;
    }
    let front = Math.floor((str.length - dl) / 2);
    if (front === 0) {
      front = 1;
    }
    return (
      str.substr(0, front) + dlstr + str.substr(front + dl, str.length - 1)
    );
  }
  async getMailInfo(id) {
    const result: any = await this.prisma.postOffice.findUnique({
      where: {
        id: +id,
      },
    });
    result.sendDate = moment(result.sendDate).format('YYYY-MM-DD');
    return result;
  }
  /**
   * 测试发信
   * @param 参数名 {参数类型} 描述信息
   * @returns 返回数据的的描述
   */
  testSendMail() {
    return this.findEmailTask();
  }
  async findEmailTask() {
    const prisma = new PrismaClient();
    const result = await prisma.postOffice.findMany({
      where: {
        sendDate: new Date(dateFormat(new Date())),
        status: 'READYTOSEND',
      },
    });
    // this.sednMail('qingbo789@aliyun.com', 'e.content');
    result.forEach((e, i) => {
      setTimeout(() => {
        this.sednMailTask(e.emailAddress, e.name, e.content, e.id);
      }, 1000 * 60 * i); //
    });
  }
  async sednMailTask(
    addressee: string,
    name: string,
    content: string,
    id: number,
  ) {
    const sendAddress = '42873016@qq.com';
    //引入模块 nodemailer
    // 创建一个SMTP客户端配置
    const config = {
      service: 'QQ',
      auth: {
        // 发件人邮箱账号
        user: sendAddress,
        //发件人邮箱的授权码 这里可以通过qq邮箱获取 并且不唯一
        pass: 'syvakvmcsthmbief',
      },
    };
    const transporter = nodemailer.createTransport(config);
    const mail = {
      // 发件人 邮箱  '昵称<发件人邮箱>'
      from: `时光邮局<42873016@qq.com>'`,
      // 主题
      subject: `${name}！！！时光邮局这有一封你的信`,
      // 收件人 的邮箱 可以是其他邮箱 不一定是qq邮箱
      to: addressee,
      //这里可以添加html标签
      html: `<div>${content}</div>`,
    };
    let result = '';
    try {
      result = await transporter.sendMail(mail);
      await this.prisma.postOffice.update({
        where: {
          id,
        },
        data: {
          status: 'FINISH',
        },
      });
    } catch (e) {
      console.log('error', e);
    }
    return result;
  }
}
